package com.gzhryc.common.config;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.commons.lang3.StringUtils;
import org.dom4j.Document;

import com.gzhryc.common.config.I18nTools.I18n;
import com.gzhryc.common.config.models.EnumEntity;
import com.gzhryc.common.xml.XmlTools;
import com.gzhryc.common.xml.annotation.XmlElement;

public class EnumTools {

	static String filePath;
	static Listener mListener;
	
	static ConcurrentHashMap<String,EnumEntity> Store = new ConcurrentHashMap<String,EnumEntity>();
	
	public static void load(String path){
		load(new File(path));
	}
	
	public static void load(File file){
		if(file.exists()){
			try {
				FileInputStream ins = new FileInputStream(file);
				Document document = XmlTools.buildDocument(ins);
				Data data = XmlTools.changToObject(document, Data.class, false);
				if(data != null && data.enums != null && data.enums.size() > 0){
					for(EnumEntity enumEntity:data.getEnums()){
						Store.put(enumEntity.getKey(),enumEntity);
					}
				}
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			}
		}
	}
	
	public static void load(InputStream ins) {
		if(ins != null) {
			Document document = XmlTools.buildDocument(ins);
			Data data = XmlTools.changToObject(document, Data.class, false);
			if(data != null && data.enums != null && data.enums.size() > 0){
				for(EnumEntity enumEntity:data.getEnums()){
					Store.put(enumEntity.getKey(),enumEntity);
				}
			}
		}
	}
	
	public static void setListener(Listener listener) {
		mListener = listener;
	}
	
	public static EnumEntity getEnum(String key){
		EnumEntity entity = Store.get(key);
		if(entity == null && mListener != null) {
			entity = mListener.findByType(key);
			if(entity != null) {
				Store.put(key, entity);
			}
		}
		return entity;
	}
	
	public static List<EnumEntity.Item> getEnumItems(String key){
		EnumEntity entity = Store.get(key);
		if(entity == null && mListener != null) {
			entity = mListener.findByType(key);
			if(entity != null) {
				Store.put(key, entity);
			}
		}
		if(entity != null){
			return entity.getItems();
		}
		return null;
	}
	
	public static String getIndexByNote(String key,String note){
		if(StringUtils.isNotBlank(key) && StringUtils.isNotBlank(note)) {
			EnumEntity enumEntity = Store.get(key);
			if(enumEntity == null && mListener != null) {
				enumEntity = mListener.findByType(key);
				if(enumEntity != null) {
					Store.put(key, enumEntity);
				}
			}
			if(enumEntity != null){
				for(EnumEntity.Item item : enumEntity.getItems()){
					if(item.getNote().equals(note)){
						String index = item.getIndex();
						return index;
					}
				}
			}
		}
		return null;
	}
	
	public static String getIndexByName(String key,String name){
		if(StringUtils.isNotBlank(key) && StringUtils.isNotBlank(name)) {
			EnumEntity enumEntity = Store.get(key);
			if(enumEntity == null && mListener != null) {
				enumEntity = mListener.findByType(key);
				if(enumEntity != null) {
					Store.put(key, enumEntity);
				}
			}
			if(enumEntity != null){
				for(EnumEntity.Item item : enumEntity.getItems()){
					if(item.getName().equals(name)){
						String index = item.getIndex();
						return index;
					}
				}
			}
		}
		return null;
	}
	
	public static Integer getIntIndexByName(String key,String name) {
		String index = getIndexByName(key,name);
		if(StringUtils.isNotBlank(index)) {
			return Integer.valueOf(index);
		}
		return null;
	}
	
	public static String getNote(String key,Integer index){
		if(index != null) {
			return getNote(key,index.toString());
		}
		return null;
	}
	
	public static String getNote(String key,String index){
		if(StringUtils.isNotBlank(key) && index != null) {
			EnumEntity enumEntity = Store.get(key);
			if(enumEntity == null && mListener != null) {
				enumEntity = mListener.findByType(key);
				if(enumEntity != null) {
					Store.put(key, enumEntity);
				}
			}
			if(enumEntity != null){
				for(EnumEntity.Item item : enumEntity.getItems()){
					if(item.index().equals(index)){
						String note = item.note();
						I18n i18n = I18nTools.getCurrentI18n();
						if(i18n != null){
							String temp = i18n.getProperties().getProperty(item.getName());
							if(StringUtils.isNotBlank(temp)){
								note = temp;
							}
						}
						return note;
					}
				}
			}
		}
		return null;
	}
	
	public static String getNote(String key,String index,String defaultNote){
		String note = getNote(key,index);
		if(StringUtils.isNotBlank(note)){
			return note;
		}
		return defaultNote;
	}
	
	/**
	 * 移除
	 * @param key
	 * @return
	 */
	public static EnumEntity remove(String key) {
		return Store.remove(key);
	}
	
	/**
	 * 刷新枚举
	 */
	public static void refresh() {
		Enumeration<String> enumeration = Store.keys();
		List<String> keys = new ArrayList<String>();
		while(enumeration.hasMoreElements()) {
			String key = enumeration.nextElement();
			EnumEntity entity = Store.get(key);
			if(entity.getCanUpdate()) {
				keys.add(key);
			}
		}
		for(String key : keys) {
			Store.remove(key);
		}
	}
	
	public static interface Listener {
		
		public EnumEntity findByType(String type);
	}
	
	public static class Data {
		
		@XmlElement("enum")
		private List<EnumEntity> enums;

		public List<EnumEntity> getEnums() {
			return enums;
		}
	}

}
